package com.oss.web;

import java.io.IOException;
import java.util.List;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.support.SessionStatus;

import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
import com.oss.model.Link;
import com.oss.model.Project;
import com.oss.model.Site;
import com.oss.model.Tag;
import com.oss.model.Topic;
import com.oss.validation.LinkValidator;
import com.oss.validation.ProjectValidator;
import com.oss.validation.TagValidator;

/**
 * @author xueqiang.mi
 * @date 2010-2-8
 */
@Controller
public class AdminController extends BaseController {

	@RequestMapping(value = "/admin/addLink.do", method = RequestMethod.POST)
	public String addHandler(@ModelAttribute Link link, BindingResult result,
			SessionStatus status) {
		new LinkValidator().validate(link, result);
		if (result.hasErrors()) {
			return "admin/linkForm";
		} else {
			lnkService.add(link);

			status.setComplete();
			return "redirect:/admin/links.do";
		}
	}

	@RequestMapping(value = "/admin/addProject.do", method = RequestMethod.POST)
	public String addHandler(@ModelAttribute Project project,
			BindingResult result, SessionStatus status) {
		new ProjectValidator().validate(project, result);
		if (result.hasErrors()) {
			return "admin/projectForm";
		} else {
			// set created author for project
			UserService userService = UserServiceFactory.getUserService();
			User user = userService.getCurrentUser();
			if (user != null) {
				project.setCreatedAuthor(user);
			}
			// enables the projects added by administrator
			project.setEnabled(true);
			prjService.add(project);

			status.setComplete();
			return "redirect:/admin/tag.do?id=" + project.getTag();
		}
	}

	@RequestMapping(value = "/admin/addTag.do", method = RequestMethod.POST)
	public String addHandler(@ModelAttribute Tag tag, BindingResult result,
			SessionStatus status) {
		new TagValidator().validate(tag, result);
		if (result.hasErrors()) {
			return "admin/tagForm";
		} else {
			tagService.add(tag);

			status.setComplete();
			return "redirect:/admin/index.do";
		}
	}

	@RequestMapping(value = "/admin/addTopic.do", method = RequestMethod.POST)
	public String addHandler(@ModelAttribute Topic topic, BindingResult result,
			SessionStatus status) {
		topicService.add(topic);

		status.setComplete();
		return "redirect:/admin/index.do";
	}

	@RequestMapping(value = "/admin/addLink.do", method = RequestMethod.GET)
	public String addLink(Model model) {
		Link link = new Link();
		model.addAttribute(link); // or model.addAttribute("link", link);

		return "admin/linkForm";
	}

	@RequestMapping(value = "/admin/addProject.do", method = RequestMethod.GET)
	public String addProject(Model model,
			@RequestParam(value = "tid", required = false) String tid)
			throws IOException {
		Project prj = new Project();
		prj.setTag(tid);
		model.addAttribute(prj);

		return "admin/projectForm";
	}

	@RequestMapping(value = "/admin/addTag.do", method = RequestMethod.GET)
	public String addTag(Model model,
			@RequestParam(value = "pid", required = false) String pid) {
		Tag tag = new Tag();
		tag.setParent(pid);
		model.addAttribute(tag);

		return "admin/tagForm";
	}

	@RequestMapping(value = "/admin/addTopic.do", method = RequestMethod.GET)
	public String addTopic(Model model) {
		Topic topic = new Topic();
		model.addAttribute(topic);

		return "admin/topicForm";
	}

	@RequestMapping(value = "/admin/batchEditLnks.do", method = RequestMethod.GET)
	public String batchEditLnks(
			Model model,
			@RequestParam(value = "prj", required = false) String prj,
			@RequestParam(value = "pageIndex", required = false) Long pageIndex,
			@RequestParam(value = "pageSize", required = false) Long pageSize) {
		if (null == prj || "".equals(prj)) {
			return "redirect:/admin/batchEditLnks.do?prj=notSet";
		}
		if (pageIndex == null || pageSize == null) {
			return "redirect:/admin/batchEditLnks.do?prj=" + prj
					+ "&pageIndex=1&pageSize=80";
		}
		List<Link> lnks = lnkService.getLnksByPrj("admin", prj, pageIndex,
				pageSize);
		model.addAttribute("lnks", lnks);
		return "admin/batchEditLnks";
	}

	@RequestMapping(value = "/admin/batchEditPrjs.do", method = RequestMethod.GET)
	public String batchEditPrjs(
			Model model,
			@RequestParam(value = "tagId", required = false) String tagId,
			@RequestParam(value = "pageIndex", required = false) Long pageIndex,
			@RequestParam(value = "pageSize", required = false) Long pageSize) {
		if (null == tagId || "".equals(tagId)) {
			return "redirect:/admin/batchEditPrjs.do?tagId=others";
		}
		if (pageIndex == null || pageSize == null) {
			return "redirect:/admin/batchEditPrjs.do?tagId=" + tagId
					+ "&pageIndex=1&pageSize=80";
		}
		List<Project> prjs = prjService.getPrjsByTag("admin", tagId, pageIndex,
				pageSize);
		model.addAttribute("prjs", prjs);
		return "admin/batchEditPrjs";
	}

	@RequestMapping(value = "/admin/deleteProject.do", method = RequestMethod.GET)
	public String deleteProject(@RequestParam("id") String id) {
		String tagId = prjService.delete(id);
		return "redirect:/admin/tag.do?id=" + tagId;
	}

	@RequestMapping(value = "/admin/deleteSite.do", method = RequestMethod.GET)
	public String deleteSite(@RequestParam("id") String id) {
		siteService.delete(Site.class, id);
		return "redirect:/admin/index.do";
	}

	@RequestMapping(value = "/admin/deleteTag.do", method = RequestMethod.GET)
	public String deleteTag(@RequestParam("id") String id) {
		tagService.delete(Tag.class, id);
		return "redirect:/admin/index.do";
	}

	@RequestMapping(value = "/admin/deleteTopic", method = RequestMethod.GET)
	public String deleteTopic(@RequestParam("id") String id) {
		topicService.delete(Topic.class, id);
		return "redirect:/admin/index.do";
	}

	@RequestMapping(value = "/admin/editLink.do", method = RequestMethod.POST)
	public String editHandler(@ModelAttribute Link link, BindingResult result,
			SessionStatus status, @RequestParam("id") String id) {
		new LinkValidator().validate(link, result);
		if (result.hasErrors()) {
			return "admin/linkForm";
		} else {
			lnkService.update(link);

			status.setComplete();
			return "redirect:/admin/links.do";
		}
	}

	@RequestMapping(value = "/admin/editProject.do", method = RequestMethod.POST)
	public String editHandler(@ModelAttribute Project project,
			BindingResult result, SessionStatus status,
			@RequestParam("id") String id) {
		new ProjectValidator().validate(project, result);
		if (result.hasErrors()) {
			return "admin/projectForm";
		} else {
			// project.setId(id);
			prjService.update(project);

			status.setComplete();
			return "redirect:/admin/tag.do?id=" + project.getTag();
		}
	}

	@RequestMapping(value = "/admin/editTag.do", method = RequestMethod.POST)
	public String editHandler(@ModelAttribute Tag tag, BindingResult result,
			SessionStatus status, @RequestParam("id") String id) {
		new TagValidator().validate(tag, result);
		if (result.hasErrors()) {
			return "admin/tagForm";
		} else {
			tagService.update(tag);

			status.setComplete();
			return "redirect:/admin/index.do";
		}
	}

	@RequestMapping(value = "/admin/editLink.do", method = RequestMethod.GET)
	public String editLink(Model model, @RequestParam("id") Long id) {
		model.addAttribute(lnkService.get(id));
		// or model.addAttribute("link", lnkService.get(id));
		return "admin/linkForm";
	}

	@RequestMapping(value = "/admin/editProject.do", method = RequestMethod.GET)
	public String editProject(Model model, @RequestParam("id") String id) {
		Project prj = prjService.get(id);
		model.addAttribute(prj);
		return "admin/projectForm";
	}

	@RequestMapping(value = "/admin/editTag.do", method = RequestMethod.GET)
	public String editTag(Model model, @RequestParam("id") String id) {
		model.addAttribute(tagService.get(id));
		return "admin/tagForm";
	}

	@RequestMapping("/admin/index.do")
	public void indexHandler(Model model) {
	}

	@RequestMapping("/admin/projectsByPage.do")
	public String prjsByPageHandler(Model model,
			@RequestParam("pageIndex") Long pageIndex,
			@RequestParam("pageSize") Long pageSize) {
		// set page size range
		pageSize = pageSize > 50 ? 50 : (pageSize > 0 ? pageSize : 10);
		model.addAttribute("prjs", prjService.getPrjs(pageIndex, pageSize));
		return "admin/projects";
	}

	@RequestMapping("/admin/projects.do")
	public String prjsHandler() {
		return "redirect:/admin/projectsByPage.do?pageSize=10&pageIndex=1";
	}

	@RequestMapping("/admin/tag.do")
	public String tagHandler(
			Model model,
			@RequestParam(value = "id", required = false) String id,
			@RequestParam(value = "pageIndex", required = false) Long pageIndex,
			@RequestParam(value = "pageSize", required = false) Long pageSize) {
		if (id == null) {
			id = "blog";
		}
		if (pageIndex == null || pageSize == null) {
			return "redirect:/admin/tag.do?id=" + id
					+ "&pageIndex=1&pageSize=20";
		}
		pageIndex = pageIndex > 0 ? pageIndex : 1;
		pageSize = pageSize > 50 ? 50 : (pageSize > 0 ? pageSize : 20);
		model.addAttribute("tag", tagService.get(id));
		model.addAttribute("prjs", prjService.getPrjsByTag("admin", id,
				pageIndex, pageSize));
		return "admin/tag";
	}

	@RequestMapping("/admin/tags.do")
	public void tagsHandler() {
	}

	@RequestMapping(value = "/admin/topics.do", method = RequestMethod.GET)
	public String topicsHandler(
			Model model,
			@RequestParam(value = "pageIndex", required = false) Long pageIndex,
			@RequestParam(value = "pageSize", required = false) Long pageSize) {
		if (pageIndex == null || pageSize == null) {
			return "redirect:/admin/topics.do?pageIndex=1&pageSize=80";
		}
		List<Topic> list = topicService.getTopics(pageIndex, pageSize);
		model.addAttribute("topics", list);
		return "admin/topics";
	}

}
